# cmake_minimum_required(VERSION 3.16)
# project(Ascend_c)

# set(RUN_MODE "npu" CACHE STRING "cpu/sim/npu")
# set(SOC_VERSION "Ascend310P3" CACHE STRING "system on chip type")
# set(ASCEND_CANN_PACKAGE_PATH "/usr/local/Ascend/ascend-toolkit/latest"
#     CACHE STRING "ASCEND CANN package installation directory"
# )
# if(NOT CMAKE_BUILD_TYPE)
#     set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Build type Release/Debug (default Debug)" FORCE)
# endif()
# if(CMAKE_INSTALL_PREFIX STREQUAL /usr/local)
#     set(CMAKE_INSTALL_PREFIX "${CMAKE_CURRENT_LIST_DIR}/out" CACHE STRING "path for install()" FORCE)
# endif()

# # ${KERNEL_FILES} are used to compile library, push files written by ascendc in ${KERNEL_FILES}.
# # ref to cmake/npu.cmake ascendc_library, cmake/cpu.cmake add_library
# file(GLOB KERNEL_FILES ${CMAKE_CURRENT_SOURCE_DIR}/matmul_custom.cpp)

# set(CUSTOM_ASCEND310P_LIST "Ascend310P1" "Ascend310P3")

# if("${RUN_MODE}" STREQUAL "cpu")
#     include(cmake/cpu_lib.cmake)
# elseif("${RUN_MODE}" STREQUAL "sim" OR "${RUN_MODE}" STREQUAL "npu")
#     include(cmake/npu_lib.cmake)
# else()
#     message("invalid RUN_MODE: ${RUN_MODE}")
# endif()

# add_executable(ascendc_kernels_bbit
#     ${CMAKE_CURRENT_SOURCE_DIR}/matmul_call.cpp
#     ${CMAKE_CURRENT_SOURCE_DIR}/matmul_custom_tiling.cpp
# )

# target_compile_options(ascendc_kernels_bbit PRIVATE
#     $<BUILD_INTERFACE:$<$<STREQUAL:${RUN_MODE},cpu>:-g>>
#     -O2 -std=c++17 -D_GLIBCXX_USE_CXX11_ABI=0 -Wall -Werror
# )

# target_compile_definitions(ascendc_kernels_bbit PRIVATE
#     $<$<BOOL:$<IN_LIST:${SOC_VERSION},${CUSTOM_ASCEND310P_LIST}>>:CUSTOM_ASCEND310P>
#     SOC_VERSION="${SOC_VERSION}"
# )

# target_link_libraries(ascendc_kernels_bbit PRIVATE
#     $<BUILD_INTERFACE:$<$<OR:$<STREQUAL:${RUN_MODE},npu>,$<STREQUAL:${RUN_MODE},sim>>:host_intf_pub>>
#     $<BUILD_INTERFACE:$<$<STREQUAL:${RUN_MODE},cpu>:ascendcl>>
#     ascendc_kernels_${RUN_MODE}
#     tiling_api
#     register
#     platform
#     ascendalog
#     dl
# )

# install(TARGETS ascendc_kernels_bbit
#     LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
#     ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
#     RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
# )



cmake_minimum_required(VERSION 3.16)
project(Ascend_c)

# 配置选项
option(RUN_MODE "运行模式: cpu/sim/npu" "npu")
option(SOC_VERSION "SoC类型" "Ascend310P3")
option(ASCEND_CANN_PACKAGE_PATH "CANN安装路径" "/usr/local/Ascend/ascend-toolkit/latest")
option(SCLOUDPLUS_LEVEL "安全级别: 128/192/256" "128")

# 设置默认构建类型
if(NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build type (Release/Debug)" FORCE)
endif()

# 设置安装路径
if(CMAKE_INSTALL_PREFIX STREQUAL /usr/local)
    set(CMAKE_INSTALL_PREFIX "${CMAKE_CURRENT_LIST_DIR}/out" CACHE STRING "安装路径" FORCE)
endif()



# 源文件和头文件
set(SOURCES
    encode.c
    random.c
    fips202.c
    sample.c
    pke.c
    matrix.c
    util.c
    kem.c
    test.c
)

set(HEADERS
    encode.h
    random.h
    fips202.h
    sample.h
    pke.h
    matrix.h
    util.h
    kem.h
    ds_benchmark.h
    data_utils.h
    config.h
    matmul_call.h
)

file(GLOB KERNEL_FILES
    "${CMAKE_CURRENT_SOURCE_DIR}/matmul_custom.cpp"
)


# AscendC相关文件
set(ASCEND_SOURCES
    matmul_call.cpp
    matmul_custom_tiling.cpp
)
# 通用编译选项
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3 -g")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 -std=c++17 -D_GLIBCXX_USE_CXX11_ABI=0 -Wall")

# 链接库
set(LIBS
    $<BUILD_INTERFACE:$<$<OR:$<STREQUAL:${RUN_MODE},npu>,$<STREQUAL:${RUN_MODE},sim>>:host_intf_pub>>
    $<BUILD_INTERFACE:$<$<STREQUAL:${RUN_MODE},cpu>:ascendcl>>
     ascendc_kernels_${RUN_MODE}
     tiling_api
     register
     platform
     ascendalog
     crypto
     ssl
     dl
     m
)

# 根据架构设置特定选项
if(CMAKE_SYSTEM_PROCESSOR MATCHES "amd64|x86_64")
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DAMD -march=native")
    list(APPEND SOURCES aes_ni.c)
    list(APPEND HEADERS aes.h)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "arm64|aarch64|arm")
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DARM -march=armv8-a+crypto")
    list(APPEND SOURCES aes_ni_arm.c)
    list(APPEND HEADERS aes_arm.h)
endif()

# AscendC配置
set(CUSTOM_ASCEND310P_LIST "Ascend310P1" "Ascend310P3")
if("${RUN_MODE}" STREQUAL "cpu")
    include(cmake/cpu_lib.cmake)
elseif("${RUN_MODE}" STREQUAL "sim" OR "${RUN_MODE}" STREQUAL "npu")
    include(cmake/npu_lib.cmake)
else()
    message(FATAL_ERROR "无效的运行模式: ${RUN_MODE}")
endif()


# 生成三个安全级别的目标
function(add_scloudplus_target level)
    set(target_name "scloudplus${level}_aes_${RUN_MODE}")
    
    add_executable(${target_name}
        ${SOURCES}
        ${ASCEND_SOURCES}
    )
    
    target_compile_definitions(${target_name} PRIVATE
        scloudplus_l=${level}
        SOC_VERSION="${SOC_VERSION}"
        $<$<IN_LIST:${SOC_VERSION},${CUSTOM_ASCEND310P_LIST}>:CUSTOM_ASCEND310P>
    )
    
    target_compile_options(${target_name} PRIVATE
        $<$<STREQUAL:${RUN_MODE},cpu>:-g>
    )
    target_link_libraries(${target_name} PRIVATE ${LIBS})
    
endfunction()
# 确保库和可执行文件安装到对应目录（与 install 指令匹配）
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_INSTALL_PREFIX}/lib)  # 库安装到 out/lib
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_INSTALL_PREFIX}/bin)

set(CMAKE_INSTALL_RPATH "$ORIGIN/../lib")
set(CMAKE_BUILD_WITH_INSTALL_RPATH ON)
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
# 生成128/192/256三个安全级别的目标
add_scloudplus_target(128)
# add_scloudplus_target(192)
# add_scloudplus_target(256)

# 清理目标
add_custom_target(clean-all
    COMMAND ${CMAKE_COMMAND} -E remove -f
        scloudplus128_aes_* scloudplus192_aes_* scloudplus256_aes_*
    COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/CMakeFiles
    COMMAND ${CMAKE_COMMAND} -E remove -f ${CMAKE_BINARY_DIR}/Makefile
    COMMAND ${CMAKE_COMMAND} -E remove -f ${CMAKE_BINARY_DIR}/cmake_install.cmake
    COMMAND ${CMAKE_COMMAND} -E remove -f ${CMAKE_BINARY_DIR}/CMakeCache.txt
)
